﻿using Microsoft.Extensions.Configuration;
using Spectre.Console;
using Spectre.Console.Rendering;

namespace WorkTool.Helpers
{
    public static class CalendarHelper
    {
        /// <summary>
        /// 日历每列宽度
        /// </summary>
        public static int _calendarColumnWidth = 13;

        public static List<CalendarData> GetCalendarSettings(IConfigurationRoot config, int year)
        {
            var result = new List<CalendarData>();
            if (SettingsHelper._calendarSettings?.Count > 0)
            {
                var calendarSetting = SettingsHelper._calendarSettings.FirstOrDefault(x => x.Year.Equals(year));
                if (calendarSetting != null)
                {
                    foreach (var month in calendarSetting.Data)
                    {
                        foreach (var item in month.Dayoff)
                        {
                            var calendarData = new CalendarData
                            {
                                Date = new DateTime(year, month.Month, item.Day),
                                CalendarDateStatus = CalendarDateStatus.DayOff,
                                Description = item.Description,
                            };
                            result.Add(calendarData);
                        }
                        foreach (var item in month.Workdays)
                        {
                            var calendarData = new CalendarData
                            {
                                Date = new DateTime(year, month.Month, item.Day),
                                CalendarDateStatus = CalendarDateStatus.WorkingDays1,
                                Description = item.Description,
                            };
                            result.Add(calendarData);
                        }
                        foreach (var item in month.Custom)
                        {
                            var calendarData = new CalendarData
                            {
                                Date = new DateTime(year, month.Month, item.Day),
                                CalendarDateStatus = CalendarDateStatus.Custom,
                                Description = item.Description,
                            };
                            result.Add(calendarData);
                        }
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 创建日历
        /// </summary>
        /// <param name="year">年</param>
        /// <param name="month">月</param>
        /// <param name="calendarData">日历填充数据</param>
        public static void CreateCalendar(int year, int month, List<CalendarData> calendarData)
        {
            calendarData ??= [];
            // 创建表格
            var table = new Table
            {
                Border = TableBorder.Rounded,
                Title = new TableTitle($"[bold][darkcyan]{year}年{month}月[/][/]"),
                BorderStyle = new Style(Color.DarkCyan)
            };
            // CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(month)
            // 设置星期标题
            var weekDays = new[] { "[bold]周一[/]", "[bold]周二[/]", "[bold]周三[/]", "[bold]周四[/]", "[bold]周五[/]", "[bold][red]周六[/][/]", "[bold][red]周日[/][/]" };
            foreach (var day in weekDays)
            {
                table.AddColumn(new TableColumn($"[bold]{day}[/]").Width(_calendarColumnWidth).Centered());
            }
            var firstDayOfMonth = new DateTime(year, month, 1);
            var daysInMonth = DateTime.DaysInMonth(year, month);
            // 计算第一天是星期几（调整为以周一为0）
            var firstDayOfWeek = (int)firstDayOfMonth.DayOfWeek;
            firstDayOfWeek = firstDayOfWeek == 0 ? 6 : firstDayOfWeek - 1;

            var currentDay = 1;
            while (currentDay <= daysInMonth || (currentDay == 1 && firstDayOfWeek > 0))
            {
                var weekCells = new List<IRenderable>();
                // 填充每周的7天
                for (int i = 0; i < 7; i++)
                {
                    // 处理月初的空白单元格
                    if ((currentDay == 1 && i < firstDayOfWeek) || currentDay > daysInMonth)
                    {
                        weekCells.Add(new Text(" "));
                        continue;
                    }
                    var date = new DateTime(year, month, currentDay);
                    var fontStyle = new Style(Color.White);
                    if (i == 5 || i == 6)
                        fontStyle = new Style(Color.Red);
                    var textList = new List<Text>()
                    {
                        new Text($"{currentDay}", fontStyle).Centered()
                    };
                    if (date == DateTime.Now.Date)
                        textList.Add(new Text("今天", Color.Aqua).Centered());
                    if (calendarData.Any(x => x.Date.Equals(date)))
                    {
                        var index = 0;
                        foreach (var item in calendarData.Where(x => x.Date.Equals(date)).OrderBy(x => x.CalendarDateStatus))
                        {
                            var description = item.Description;
                            switch (item.CalendarDateStatus)
                            {
                                case CalendarDateStatus.WorkingDays:
                                    fontStyle = new Style(Color.White);
                                    break;

                                case CalendarDateStatus.WorkingDays1:
                                    fontStyle = new Style(Color.White);
                                    break;

                                case CalendarDateStatus.DayOff:
                                    fontStyle = new Style(Color.Red);
                                    break;

                                case CalendarDateStatus.Leave:
                                    fontStyle = new Style(Color.Yellow);
                                    description = item.CalendarLeaveData.LeaveName + " " + (item.CalendarLeaveData.LeaveTimeType.Equals(LeaveTimeType.All) ? "" : item.CalendarLeaveData.LeaveTimeType.ToString());
                                    break;

                                case CalendarDateStatus.Custom:
                                    fontStyle = new Style(Color.SkyBlue2);
                                    break;

                                default:
                                    break;
                            }
                            if (index == 0)
                                textList[0] = new Text($"{currentDay}", fontStyle).Centered();
                            textList.Add(new Text(description, fontStyle).Centered());
                            index++;
                        }
                    }

                    var panel = new Panel(new Rows([.. textList]))
                    {
                        Border = textList.Count > 1 ? BoxBorder.Rounded : BoxBorder.None,
                        BorderStyle = new Style(Color.Aqua),
                        Padding = new Padding(0, 0, 0, 0),
                        Width = _calendarColumnWidth,
                        //Height = 5
                    };
                    weekCells.Add(panel);
                    currentDay++;
                }
                table.AddRow(weekCells.Take(7).ToArray());
            }
            AnsiConsole.Write(table);
        }
    }

    public class CalendarData
    {
        /// <summary>
        /// 日期
        /// </summary>
        public DateTime Date { get; set; }

        /// <summary>
        /// 描述
        /// </summary>
        public string Description { get; set; } = string.Empty;

        /// <summary>
        /// 日期状态
        /// </summary>
        public CalendarDateStatus CalendarDateStatus { get; set; }

        /// <summary>
        /// 休假数据
        /// </summary>
        public CalendarLeaveData? CalendarLeaveData { get; set; }
    }

    /// <summary>
    /// 休假数据
    /// </summary>
    public class CalendarLeaveData
    {
        /// <summary>
        /// 请假时间
        /// </summary>
        public LeaveTimeType LeaveTimeType { get; set; }

        /// <summary>
        /// 休假名称
        /// </summary>
        public string LeaveName { get; set; }
    }

    public enum LeaveTimeType
    {
        /// <summary>
        /// 全天
        /// </summary>
        All = 1,

        /// <summary>
        /// 上午
        /// </summary>
        AM = 2,

        /// <summary>
        /// 下午
        /// </summary>
        PM = 3,
    }

    public enum CalendarDateStatus
    {
        /// <summary>
        /// 休假
        /// </summary>
        Leave = 1,

        /// <summary>
        /// 正常工作日
        /// </summary>
        WorkingDays = 2,

        /// <summary>
        /// 补班
        /// </summary>
        WorkingDays1 = 3,

        /// <summary>
        /// 休息日
        /// </summary>
        DayOff = 4,

        /// <summary>
        /// 自定义
        /// </summary>
        Custom = 5,
    }

    public class CalendarSettings
    {
        /// <summary>
        /// 年
        /// </summary>
        public int Year { get; set; }

        /// <summary>
        /// 数据
        /// </summary>
        public List<CalendarSettingsData> Data { get; set; } = [];
    }

    public class CalendarSettingsData
    {
        /// <summary>
        /// 月
        /// </summary>
        public int Month { get; set; }

        /// <summary>
        /// 休息日
        /// </summary>
        public List<CalendarSettingsDay> Dayoff { get; set; } = [];

        /// <summary>
        /// 工作日
        /// </summary>
        public List<CalendarSettingsDay> Workdays { get; set; } = [];

        /// <summary>
        /// 自定义
        /// </summary>
        public List<CalendarSettingsDay> Custom { get; set; } = [];
    }

    public class CalendarSettingsDay
    {
        /// <summary>
        /// 天
        /// </summary>
        public int Day { get; set; }

        /// <summary>
        /// 描述
        /// </summary>
        public string Description { get; set; }
    }
}